package com.xnx3.banmahuishou.qishouApplet.controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.xnx3.banmahuishou.core.entity.Qishou;
import com.xnx3.banmahuishou.qishouApplet.Global;
import com.xnx3.banmahuishou.qishouApplet.vo.QishouVO;
import com.xnx3.j2ee.controller.BaseController;
import com.xnx3.j2ee.entity.User;
import com.xnx3.j2ee.service.SqlCacheService;
import com.xnx3.j2ee.service.SqlService;
import com.xnx3.j2ee.service.UserService;
import com.xnx3.j2ee.util.ActionLogUtil;
import com.xnx3.j2ee.vo.BaseVO;
import com.xnx3.weixin.applet.login.entity.WeixinAppletUserOpenid;
import com.xnx3.weixin.applet.login.vo.LoginVO;
import com.xnx3.weixin.vo.Jscode2sessionResultVO;
import com.xnx3.weixin.vo.PhoneVO;


/**
 * 斑马回收骑手端，自动登录、获取手机号一键登录相关控制器
 * @author 管雷鸣
 */
@Controller(value="BanmahuishouQishouWeixinAppletLoginController")
@RequestMapping("/qishouApplet/login/")
public class LoginController extends BaseController{
	@Resource
	private UserService userService;
	@Resource
	private SqlCacheService sqlCacheService;
	@Resource
	private SqlService sqlService;
	
	/**
	 * 通过 code(openid) 自动登陆 。如果result返回3，需要出现手机号一键登录，通过 bindByPhone.json
	 * <p>用到微信小程序的 wx.login 进行获取code</p>
	 * <p>1. 微信获取随机code，传入此处； </p>
	 * <p>2. 服务器通过code拉取用户 unionid；  </p>
	 * <p>3. 利用 unionid 来判断用户是否存在及设置用户自动登陆状态</p>
	 * <p>如果骑手第一次</p>
	 * @param code 微信小程序获取的随机code
	 * @param storeid 要登录哪个商铺，也就是要使用哪个商铺的微信设置的参数
	 * @param referrerid 推荐人id，这里传入的是推荐人的 user.id 这个在创建用户信息时，会跟storeid一块计入用户的 StoreUser.referrerid。 可不填
	 * @return {@link LoginVO} 登陆结果。根据getResult() 进行判断
	 * 		<ul>
	 * 			<li> {@link LoginVO}.getResult() == {@link LoginVO}.SUCCESS : 自动登陆成功。 同时，有一种情况，用户第一次登陆，也就是刚注册时，getInfo() 会返回字符串 "reg" </li>
	 * 			<li>{@link LoginVO}.getResult() == {@link LoginVO}.FAILURE : 自动登陆失败 ，可用 getInfo() 获取失败原因</li>
	 * 		</ul>
	 * @author 管雷鸣
	 */
	@RequestMapping(value="loginByOpenid.json",method = {RequestMethod.POST})
	@ResponseBody
	public LoginVO loginByCode(HttpServletRequest request,
			@RequestParam(required = false, defaultValue="") String code){
		LoginVO vo = new LoginVO();
		
		//判断当前用户是否已经登录过了
		if(getUserId() > 0){
			//已登录过了
			vo.setUser(getUser());
			vo.setInfo("您已经是登录状态了，所以不再返回 userWeixin 字段了。只有未登录状态下，登录成功，才会返回 userWeixin");
			return vo;
		}
		if(code.length() == 0){
			vo.setBaseVO(LoginVO.FAILURE, "请传入您的微信小程序获取到的code");
			return vo;
		}
		if(!Global.isUse()) {
			vo.setBaseVO(LoginVO.FAILURE, "微信小程序未配置，请在 applilcation.properties 中配置");
			return vo;
		}
		
		Jscode2sessionResultVO jvo = Global.weixinAppletUtil.loginByCode(code);
		if(jvo.getResult() - Jscode2sessionResultVO.SUCCESS == 0){
			//登陆成功
			vo.setSessionKey(jvo.getSessionKey());
			
			WeixinAppletUserOpenid weixinAppletUserOpenid = sqlCacheService.findAloneByProperty(WeixinAppletUserOpenid.class, "openid", jvo.getOpenid());
			User user = null;
			if(weixinAppletUserOpenid == null){
				//此用户还未注册，需要bindByPhone.json获取手机号进行绑定
				vo.setBaseVO(3, "用户第一次用，需要通过 bindByPhone.json 进行绑定当前微信 ");
				
				weixinAppletUserOpenid = new WeixinAppletUserOpenid();
				weixinAppletUserOpenid.setOpenid(jvo.getOpenid());
				vo.setWeixinAppletUserOpenid(weixinAppletUserOpenid);
				ActionLogUtil.insertUpdateDatabase(request, "该用户未绑定手机号，获取手机号绑定");
			}else{
		
				//用户已经注册过了
				//设置当前用户为登陆的状态
				BaseVO loginVO = userService.loginForUserId(request, weixinAppletUserOpenid.getUserid());
				ActionLogUtil.insertUpdateDatabase(request, "微信小程序登录--debug", weixinAppletUserOpenid.toString()+", "+loginVO.toString());
				//TODO 用于审核
//				BaseVO loginVO = userService.loginForUserId(request, 431);
				if(loginVO.getResult() - BaseVO.FAILURE == 0){
					vo.setBaseVO(LoginVO.FAILURE, loginVO.getInfo());
					return vo;
				}
				
//				user = getUser();缓存有问题,注释掉,从数据库查询
				user = sqlService.findById(User.class, weixinAppletUserOpenid.getUserid());
				vo.setUser(user);
				vo.setWeixinAppletUserOpenid(weixinAppletUserOpenid);
				
				ActionLogUtil.insertUpdateDatabase(request, user.getId(), "微信小程序登录,"+user.toString());
			}
			
		}else{
			// jscode2session 获取失败
			vo.setBaseVO(BaseVO.FAILURE, jvo.getInfo());
		}
		
		vo.setToken(request.getSession().getId());
		ActionLogUtil.insert(request,"微信小程序登录,返回vo "+vo.toString());
		return vo;
	}
	
	/**
	 * 通过手机号登录。如果用户是第一次登录，还没关联骑手本身openid，才会走这一步
	 * @param sessionKey 用户通过小程序code登录成功后获得的sessionKey
	 * @param encryptedData 小程序通过 open-type=getPhoneNumber 按钮获取的手机号加密信息
	 * @param iv 小程序通过 open-type=getPhoneNumber 按钮获取的
	 * @param openid 用户微信的openid，通过 loginByCode.json 获取到的openid
	 * @return 手机号。如果 {@link PhoneVO}.getResult 为 PhoneVO.SUCCESS ，那么便是获取成功，可以通过 {@link PhoneVO#getPhone()}获取手机号
	 * @author 管雷鸣
	 */
	@RequestMapping(value="bindByPhone.json",method = {RequestMethod.POST})
	@ResponseBody
	public QishouVO bindByPhone(HttpServletRequest request,
			@RequestParam(required = true, defaultValue="") String sessionKey,
			@RequestParam(required = true, defaultValue="") String encryptedData,
			@RequestParam(required = true, defaultValue="") String iv,
			@RequestParam(required = true, defaultValue="") String openid){
		QishouVO vo = new QishouVO();
		
		PhoneVO phoneVO = Global.weixinAppletUtil.getPhone(sessionKey, encryptedData, iv);
		if(phoneVO.getResult() - BaseVO.FAILURE == 0) {
			//失败
			vo.setBaseVO(BaseVO.FAILURE, phoneVO.getInfo());
			return vo;
		}
		
		//验证此用户的手机号是否是骑手的
		Qishou qishou = sqlService.findAloneByProperty(Qishou.class, "phone", phoneVO.getPhone());
		if(qishou == null) {
			//不是骑手
			vo.setBaseVO(BaseVO.FAILURE, "您不是骑手，无法进入");
			return vo;
		}
		
		//保存 WeixinAppletUserOpenid 对应表,先查询一下有没有此记录了
		if(sqlCacheService.findAloneByProperty(WeixinAppletUserOpenid.class, "openid", openid, 3600) != null) {
			//已经绑定过openid了
			vo.setBaseVO(BaseVO.FAILURE, "系统安全防控拦截，openid 已经绑定过了，只有第一次登录时才会进行绑定。");
			return vo;
		}
		WeixinAppletUserOpenid weixinAppletUserOpenid = new WeixinAppletUserOpenid();
		weixinAppletUserOpenid.setUserid(qishou.getId());
		weixinAppletUserOpenid.setOpenid(openid);
		sqlService.save(weixinAppletUserOpenid);
		
		//记录日志及返回vo
		ActionLogUtil.insertUpdateDatabase(request, qishou.getId(), "微信小程序骑手第一次登录，绑定openid: qishou:"+qishou.toString()+", openid:"+openid);
		vo.setQishou(qishou);
		return vo;
	}
}
